package com.liyunc.demo.comp.common.rest.response;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.liyunc.demo.comp.common.data.fetch.PageableResult;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Collection;
import java.util.Objects;

/**
 * @author liyuncong
 * @version 1.0
 * @file PageableResponse
 * @brief PageableResponse
 * @details PageableResponse
 * @date 2022-04-28
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                        NAME               DESCRIPTION
 * 2022-04-28                      liyuncong          Created
 */

@EqualsAndHashCode(callSuper = true)
@Data
public class PageableResponse<T> extends AbstractResponse {
    private Iterable<T> payload;
    private PageableResult pagination;

    /**
     * 构造函数.
     */
    public PageableResponse() {
    }

    /**
     * 构造函数.
     *
     * @param code          错误码
     * @param message       错误消息
     * @param payload       消息体
     * @param pageSize      每页大小
     * @param pageIndex     页码
     * @param currentNumber 当前页数量
     * @param totalRecords  总记录数量
     * @param totalPages    总页数
     */
    public PageableResponse(
        int code, String message, Iterable<T> payload,
        int pageSize, int pageIndex, int currentNumber, Long totalRecords, int totalPages
    ) {
        super(code, message);
        this.payload = payload;
        this.pagination =
            PageableResult.of(pageSize, pageIndex, currentNumber, totalRecords, totalPages);
    }

    /**
     * 构造函数.
     *
     * @param payload       消息体
     * @param pageSize      每页大小
     * @param pageIndex     页码
     * @param currentNumber 当前页数量
     * @param totalRecords  总记录数量
     * @param totalPages    总页数
     */
    public PageableResponse(
        Collection<T> payload,
        int pageSize, int pageIndex, int currentNumber, Long totalRecords, int totalPages
    ) {
        this(0, null, payload,
            pageSize, pageIndex, currentNumber, totalRecords, totalPages);
    }

    /**
     * 快速构造方法.
     *
     * @param <T> 消息体类型
     * @return PageableResponse
     */
    public static <T> PageableResponse<T> empty() {
        return new PageableResponse<>();
    }

    /**
     * 快速构造方法.
     *
     * @param payload      消息体
     * @param pageSize     每页大小
     * @param pageIndex    页码
     * @param totalRecords 当前页数量
     * @param totalPages   总记录数量
     * @param <T>          消息体类型
     * @return PageableResponse
     */
    public static <T> PageableResponse<T> of(
        Collection<T> payload,
        int pageSize, int pageIndex, Long totalRecords, int totalPages
    ) {
        if (payload.isEmpty()) {
            return PageableResponse.empty();
        }
        return new PageableResponse<>(
            payload,
            pageSize,
            pageIndex,
            payload.size(),
            totalRecords,
            totalPages
        );
    }

    /**
     * 快速构造方法.
     *
     * @param payload 消息体
     * @param page    分页结果
     * @param <T>     消息体类型
     * @return PageableResponse
     */
    public static <T> PageableResponse<T> of(
        Collection<T> payload, PageableResult page
    ) {
        if (Objects.isNull(payload) || Objects.isNull(page)) {
            return empty();
        }
        return PageableResponse.of(
            payload,
            page.getSize(),
            page.getIndex(),
            page.getTotalRecords(),
            page.getTotalPages()
        );
    }

    /**
     * 快速构造方法.
     *
     * @param payload 消息体
     * @param page    分页结果
     * @param <T>     消息体类型
     * @return PageableResponse
     */
    public static <T> PageableResponse<T> of(
        Collection<T> payload, IPage<?> page) {
        if (Objects.isNull(payload) || Objects.isNull(page)) {
            return empty();
        }
        return PageableResponse.of(
            payload,
            (int) page.getSize(),
            (int) page.getCurrent(),
            page.getTotal(),
            (int) page.getPages()
        );
    }
}
